﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

using PasswordProvider.ObjectModel;
using PasswordProvider.ViewModel.Framework;
using PasswordProvider.ViewModel.Properties;

namespace PasswordProvider.ViewModel
{
    public class CreditCardDetailsViewModel : SiteDetailsViewModel
    {
        private LogOnSite _nullSite = new LogOnSite(null, null, null, null);

        internal CreditCardDetailsViewModel(CreditCardSite site, bool isNew)
            : base(site, isNew)
        {
        }

        #region Overrides

        /// <summary>
        /// Transfer the properties from this view model to the underlying Site.
        /// </summary>
        protected override void TransferProperties()
        {            
            CardNumber.CommitNewValue();
            Code.CommitNewValue();
            Pin.CommitNewValue();
            CreditCardSite creditCard = (CreditCardSite)Site;
            creditCard.ExpirationMonth = ExpirationMonth.SelectedItem;
            creditCard.ExpirationYear = ExpirationYear.SelectedItem;

            creditCard.IssuingCompany = IssuingCompany.Text;
            creditCard.CompanyPhone = CompanyPhone.Text;
            creditCard.NameOnCard = NameOnCard.Text;

            creditCard.Website = _webSite.SelectedItem;            
            if (creditCard.Website == _nullSite)
                creditCard.Website = null;
        }

        #endregion // overrides

        #region Public Properties

        public static string IdentityGroupDisplayName
        {
            get { return Strings.CreditCardDetails_IdentityGroupDisplayName; }
        }

        public static string DataGroupDisplayName
        {
            get { return Strings.CreditCardDetails_DataGroupDisplayName; }
        }

        public ListSelectViewModel<LogOnSite> Website
        {
            get
            {
                if (_webSite == null)
                {
                    CreditCardSite creditCard = (CreditCardSite)Site;
                    LogOnSite webSite = creditCard.Website;

                    List<LogOnSite> listOfSites = GetLogOnSites();
                    listOfSites.Sort((a, b) => String.Compare(a.Name, b.Name, true, CultureInfo.CurrentUICulture));
                    listOfSites.Insert(0, _nullSite);
                    
                    _webSite = new ListSelectViewModel<LogOnSite>(
                        "Web Site", "Select a web site from the list which is the web site for this credit card.",
                        listOfSites,
                        webSite);
                    _webSite.SelectedItemChanged += delegate { OnPropertyChanged("Website"); };
                }
                return _webSite;
            }
        } private ListSelectViewModel<LogOnSite> _webSite;


        /// <summary>
        /// The credit card number.
        /// </summary>
        public EncryptedValueViewModel CardNumber
        {
            get
            {
                if (_cardNumber == null)
                {
                    _cardNumber = new EncryptedValueViewModel(
                        Strings.CreditCardDetails_CardNumber_DisplayName,
                        Strings.CreditCardDetails_CardNumber_ToolTip, 16,
                        (Site as CreditCardSite).CardNumber);
                    _cardNumber.PasswordChanged += delegate { OnPropertyChanged("CardNumber"); };                    
                }
                return _cardNumber;
            }
        } private EncryptedValueViewModel _cardNumber;

        /// <summary>
        /// The credit card security code.
        /// </summary>
        public EncryptedValueViewModel Code
        {
            get
            {
                if (_code == null)
                {
                    _code = new EncryptedValueViewModel(
                        Strings.CreditCardDetails_Code_DisplayName,
                        Strings.CreditCardDetails_Code_ToolTip, 3,
                        (Site as CreditCardSite).Code);
                    _code.PasswordChanged += delegate { OnPropertyChanged("Code"); };
                }
                return _code;
            }
        } private EncryptedValueViewModel _code;

        /// <summary>
        /// Pin: The card's PIN if it is a debit card.
        /// </summary>
        public EncryptedValueViewModel Pin
        {
            get
            {
                if (_pin == null)
                {
                    _pin = new EncryptedValueViewModel(
                        Strings.CreditCardDetails_Pin_DisplayName,
                        Strings.CreditCardDetails_Pin_ToolTip, 4,
                        (Site as CreditCardSite).Pin);
                    _pin.PasswordChanged += delegate { OnPropertyChanged("Pin"); };
                }
                return _pin;
            }            
        } private EncryptedValueViewModel _pin;

        /// <summary>
        /// ShowHiddenValues: Whether or not to show the credit card number, security code, and pin.
        /// </summary>
        public ToggleViewModel ShowHiddenValues
        {
            get
            {
                if (_showHiddenValues == null)
                {
                    _showHiddenValues = new ToggleViewModel(
                        Strings.CreditCardDetails_ShowHidden_DisplayName,
                        Strings.CreditCardDetails_ShowHidden_ToolTip,
                        CardNumber.ShowClearText);
                    _showHiddenValues.IsCheckedChanged += new ValueChangedEventHandler<bool>(ShowHiddenValues_IsCheckedChanged);
                        
                }
                return _showHiddenValues;
            }
        } private ToggleViewModel _showHiddenValues;

        /// <summary>
        /// ExpirationDateDisplayName: The display name for the expiration date label.
        /// </summary>
        public static string ExpirationDateDisplayName
        {
            get { return Strings.CreditCardDetails_Date_DisplayName; }
        }
        /// <summary>
        /// The ExpirationMonth drop down.
        /// </summary>
        public ListSelectViewModel<string> ExpirationMonth
        {
            get
            {
                if (_expirationMonth == null)
                {
                    _expirationMonth = new ListSelectViewModel<string>(
                        Strings.CreditCardDetails_Date_Month_DisplayName,
                        null,
                        new string[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" },
                        (Site as CreditCardSite).ExpirationMonth);
                    _expirationMonth.SelectedItemChanged += delegate { OnPropertyChanged("ExpirationMonth"); };
                }
                return _expirationMonth;
            }
        } private ListSelectViewModel<string> _expirationMonth;

        /// <summary>
        /// Experation year combo box.
        /// </summary>
        public ListSelectViewModel<string> ExpirationYear
        {
            get
            {
                if (_expirationYear == null)
                {
                    _expirationYear = new ListSelectViewModel<string>(
                        Strings.CreditCardDetails_Date_Year_DisplayName,
                        null, GenerateExpirationYears(),
                        (Site as CreditCardSite).ExpirationYear);
                    _expirationYear.SelectedItemChanged += delegate { OnPropertyChanged("ExpirationYear"); };
                }
                return _expirationYear;
            }
        } private ListSelectViewModel<string> _expirationYear;


        /// <summary>
        /// Issuing Company Name.
        /// </summary>
        public TextEditViewModel IssuingCompany
        {
            get
            {
                if (_issuingCompany == null)
                {
                    _issuingCompany = new TextEditViewModel(
                        Strings.CreditCardDetails_IssuingCompany_DisplayName,
                        Strings.CreditCardDetails_IssuingCompany_ToolTip,
                        (Site as CreditCardSite).IssuingCompany);
                    _issuingCompany.TextValueChanged += delegate { OnPropertyChanged("IssuingCompany"); };
                }
                return _issuingCompany;
            }
        } private TextEditViewModel _issuingCompany;

        /// <summary>
        /// Company Phone Number.
        /// </summary>
        public TextEditViewModel CompanyPhone
        {
            get
            {
                if (_companyPhone == null)
                {
                    _companyPhone = new TextEditViewModel(
                        Strings.CreditCardDetails_CompanyPhone_DisplayName,
                        Strings.CreditCardDetails_CompanyPhone_ToolTip,
                        (Site as CreditCardSite).CompanyPhone);
                    _companyPhone.TextValueChanged += delegate { OnPropertyChanged("CompanyPhone"); };
                }
                return _companyPhone;
            }
        } private TextEditViewModel _companyPhone;


        /// <summary>
        /// Name On Card text edit.
        /// </summary>
        public TextEditViewModel NameOnCard
        {
            get
            {
                if (_nameOnCard == null)
                {
                    _nameOnCard = new TextEditViewModel(
                        Strings.CreditCardDetails_NameOnCard_DislpayName,
                        Strings.CreditCardDetails_NameOnCard_ToolTip,
                        (Site as CreditCardSite).NameOnCard);
                    _nameOnCard.TextValueChanged += delegate { OnPropertyChanged("NameOnCard"); };
                }
                return _nameOnCard;
            }
        } private TextEditViewModel _nameOnCard;


        #endregion // Public Properties

        #region // Private Helpers


        private static List<LogOnSite> GetLogOnSites()
        {
            List<LogOnSite> list = new List<LogOnSite>();

            // Add the existing LogOnSites
            foreach (Site site in PasswordProviderData.Current.Sites)
            {
                LogOnSite logOn = site as LogOnSite;
                if (logOn != null)
                    list.Add(logOn);
            }

            return list;

        }

        /// <summary>
        /// Show or hide the card number, pin and security code based on ShowHiddenValues.IsChecked.
        /// </summary>
        void ShowHiddenValues_IsCheckedChanged(bool isChecked)
        {
            CardNumber.ShowClearText = Pin.ShowClearText = Code.ShowClearText = isChecked;
        }

        /// <summary>
        /// Generate a list of years for the drop down of Expiration Year.
        /// </summary>
        private static IEnumerable<string> GenerateExpirationYears()
        {
            List<string> years = new List<string>();

            // begin with a couple years before current, go to 10 or so years after.
            int currentYear = DateTime.Now.Year;
            for (int year = currentYear - 2; year < currentYear + 12; year++)
            {
                years.Add(Convert.ToString(year, CultureInfo.CurrentCulture));
            }

            return years;
        }

        #endregion
    }
}
